package Fachada;

import java.util.Date;
import java.util.List;

import Basicas.Apartamento;
import Basicas.Cliente;
import Basicas.Hospedagem;
import Basicas.Pagamento;
import Basicas.Produto;
import Basicas.SituacaoApartamento;
import Basicas.TipoApartamento;
import Basicas.TipoOcupacao;
import Basicas.Usuario;
import Exception.AlterarException;
import Exception.ApartamentoJaExisteException;
import Exception.ErroLogarException;
import Exception.ErroLoginInativoException;
import Exception.EstoqueBaixoException;
import Exception.GenericoException;
import Exception.InserirException;
import Exception.PernoiteNaoPermitidaException;
import Exception.RelatorioVazioException;
import Exception.RemoverException;
import ModelRelatorio.RelatorioPorHora;
import ModelRelatorio.RelatorioPorMes;
import Negocio.RNApartamento;
import Negocio.RNCliente;
import Negocio.RNHospedagem;
import Negocio.RNPagamento;
import Negocio.RNProduto;
import Negocio.RNUsuario;

public class Fachada implements IFachada {
	
	private static Fachada fachada;
	private RNApartamento RNAp;
	private RNUsuario RNUsu;
	private RNProduto RNPr;
	private RNCliente RNcli;
	private RNHospedagem RNHosp;
	private RNPagamento RNPag;

	private Fachada() {	
		this.RNAp = new RNApartamento();
		this.RNUsu = new RNUsuario();
		this.RNPr = new RNProduto();
		this.RNcli = new RNCliente();
		this.RNHosp = new RNHospedagem();
		this.RNPag = new RNPagamento();
	}	
	
	public static synchronized Fachada getFachada(){
		if(fachada == null){
			fachada = new Fachada();
		}
		return fachada;	
	}
	
	@Override
	public void apartamentoInserir(Apartamento ap) throws ApartamentoJaExisteException, InserirException {
			
		    RNAp.findByExistente(ap.getNumero());
			RNAp.inserir(ap);

	}
	@Override
	public void apartamentoAlterar(Apartamento ap) throws  AlterarException, ApartamentoJaExisteException {
			
			RNAp.findByExistenteAlt(ap);
			RNAp.alterarApartamento(ap);
		
	}
	
	
	@Override
	public void apartamentoExcluir(Apartamento ap) throws  RemoverException {
		 
		RNAp.removerApartamento(ap);
	}
	@Override
	public List<Apartamento> apartamentoListarTodos() {
		
		return RNAp.listarApartamentos();
	}
	
	@Override
	public List<Apartamento> apartamentoListarSituacao(SituacaoApartamento sit) {
		
		List<Apartamento> apts = RNAp.listarApartamentosSituacao(sit);
		return apts;
	}

	
	@Override
	public Apartamento apartamentoFindById(int id) {
		
		return RNAp.findById(id);
		
	}
	
	@Override
	public List<Apartamento> apartamentoListarTipo(TipoApartamento tipo) {
		
		return RNAp.listarApartamentosPorTipo(tipo);
	}

	
	@Override
	public List<Apartamento> apartamentoPesquisar(List<TipoApartamento> tipos,
			List<SituacaoApartamento> situacoes) {
				
		return RNAp.listarApartamentosPorParametros(tipos,situacoes);
	}
	
	/**
	 * Usuario
	 * @throws InserirException 
	 * @throws GenericoException 
	 * @throws ErroLoginInativoException 
	 * @throws ErroLogarException 
	 */
	
	
	@Override
	public void usuarioInserir(Usuario u, String senhaconfirmacao) throws InserirException, GenericoException {
		
		RNUsu.verificarSenha(u.getSenha(), senhaconfirmacao);
		RNUsu.loginUnico(u);
		RNUsu.inserir(u);
	}
	
	@Override
	public void usuarioAlterar(Usuario u) throws AlterarException, GenericoException {
		
		RNUsu.loginUnicoAlt(u);
		RNUsu.alterar(u);
	}
	@Override
	public void usuarioExcluir(Usuario u) throws RemoverException {
		
		RNUsu.excluir(u);
		
	}
	@Override
	public List<Usuario> usuarioListarTodos() {

		List<Usuario> usuarios = RNUsu.listarUsuarios();
		return usuarios;
	}
	@Override
	public Usuario usuarioPesquisar(int id) {
	
		return RNUsu.findById(id);
	}
	
	@Override
	public Usuario efetuarLogin(String login, String senha) throws ErroLogarException, ErroLoginInativoException {
		
		return RNUsu.buscarUsuario(login, senha);
	}
	
	public void alterarSenhaUsuario(Usuario usuario, String senhaNova, String senhaConfirmacao) throws GenericoException, AlterarException{
		
		RNUsu.conferirSenhas(usuario, senhaNova, senhaConfirmacao);
		usuario.setSenha(senhaNova);
		RNUsu.alterar(usuario);
	}
	
	/**
	 * Clientes
	 * @throws InserirException 
	 */
	@Override
	public void clienteInserir(Cliente c) throws InserirException {
		
		RNcli.inserir(c);
			
	}
	
	@Override
	public List<Cliente> clienteListarTodos() {
		List<Cliente>cliente = RNcli.listarClientes();
		return cliente;
	}
	
	@Override
	public void clienteAlterar(Cliente c) throws AlterarException{
		
		RNcli.alterar(c);
		
	}
	
	@Override
	public void clienteExcluir(Cliente c) throws RemoverException{
		
		RNcli.excluir(c);
		
	}
	
	
	/**
	 * Produtos
	 */
	
	@Override
	public void produtoIserir(Produto p) throws InserirException {
		RNPr.inserir(p);
		
	}
	@Override
	public void produtoAlterar(Produto p) throws AlterarException {
		RNPr.alterarProduto(p);
		
	}
	@Override
	public void produtoExcluir(Produto p) throws RemoverException {
	
		RNPr.removerProduto(p);
	}
	@Override
	public List<Produto> produtoListarTodos() {
		List<Produto>lista = RNPr.listarProdutos();
		return lista;
	}
	@Override
	public void verificarEstoque(Produto p) throws EstoqueBaixoException{
		
		RNPr.consultarEstoque(p);
	}
	
	
	//login
	@Override
	public Boolean realizarLogin(String login, String senha) {
		return null;
	}
	
	//Hospedagem
	public List<Hospedagem> hospedagemListarTodas(){
		List<Hospedagem>lista = RNHosp.listarTodas();
		return lista;
	}
	@Override
	public void realizarHospedagem(Hospedagem hospedagem,Cliente cliente) throws InserirException {
		
		RNHosp.inserir(hospedagem,cliente);
		
	}
	
	public void validarHospedagem(TipoOcupacao tipo) throws PernoiteNaoPermitidaException{
		
		RNHosp.verificarPernoite(tipo);
	}
	
	public Hospedagem obterHospedagemPorAp(Apartamento ap, SituacaoApartamento sit){
		return RNHosp.obterHospedagemPorAp(ap, sit);
	}
	@Override
	public void cancelarHospedagem(Hospedagem hospedagem) {
		
		
	}
	@Override
	public void registrarConsumo(Integer numeroAP, Produto p,
			Integer qntConsumida, Double valorConsumido) throws InserirException {
      
	}
	@Override
	public void fecharConta(Hospedagem hosp) throws AlterarException {
		RNHosp.fecharConta(hosp);

	}
	@Override
	public void registarPagamento(Hospedagem h,Pagamento p) throws InserirException {
		
		RNPag.fazerPagamento(h,p);
	}
	@Override
	public void refazerConta() {
		
	}
	@Override
	public void encerarHospedagem(Integer numeroAP) {
		
	}	
	public Double fazerConta(Pagamento p){
		
		return RNPag.fazerConta(p);
		
	}
	public Double calcularValorAdicional(Date previsto){
				
		return RNHosp.obterValorAdicional(previsto);
	}
	public void conta(Pagamento p) throws InserirException{
		
		RNPag.conta(p);
	}
	
	public void efetuarPagamento(Pagamento pagamento) throws InserirException{
		
		RNPag.pagar(pagamento);
	}
	
	
	
	
	public List<RelatorioPorMes> relatorioMovimentacaoPorMes(Integer ano) throws RelatorioVazioException{
		
		return RNHosp.obterRelatorioMovimentacaoMensal(ano);
	}
	
public List<RelatorioPorHora> relatorioMovimentacaoPorHora(Date inicio, Date fim) throws RelatorioVazioException{
		
		return RNHosp.relatorioEntrePeriodo(inicio, fim);
	}
}
